/*
 * @Author: yanjikun
 * @Date: 2022-04-11 17:53:22
 * @LastEditors: yanjikun
 * @LastEditTime: 2022-05-05 17:31:26
 * @Description: file content
 */

import { isArray, isFunction, isObject, isString } from '@/utils/is'
import { Ref, unref, VNode } from 'vue'
import { DynamicTableEmits, DynamicTableProps } from '../dynamic-table'
import { TableColumn } from '../types/column'
import { OnChangeCallbackParams } from '../types/table'
import { TableState } from './useTableState'

export type TableMethods = ReturnType<typeof useTableMethods>

export type UseTableMethodsContext = {
  state: TableState
  props: DynamicTableProps
  emit: DynamicTableEmits
}

export const useTableMethods = ({ state, props, emit }: UseTableMethodsContext) => {
  const { innerPropsRef, tableData, paginationRef, loadingRef } = state
  const setProps = (props: Partial<DynamicTableProps>) => {
    innerPropsRef.value = { ...unref(innerPropsRef), ...props }
  }
  const getComponent = (comp: VNode | string) => {
    return isString(comp) ? <>{comp}</> : comp
  }
  /**
   * @description: 表格查询
   * @param {*} params
   * @return {*}
   * @author: yanjikun
   */
  const queryTable = (params) => {
    params.pageSize = 1
    fetchData(params)
  }
  /**
   * @description: 获取表格数据
   * @param {object} params 表格查询参数
   * @return {array} 表格数据
   * @author: yanjikun
   */
  const fetchData = async (params: Recordable = {}): Promise<Ref<any[]>> => {
    /**如果提供dataSource或者dataRequest不是一个函数，就直接返回数据 */
    if (!(Object.is(props.dataSource, undefined) && isFunction(props.dataRequest))) {
      return tableData
    }
    const _pagination = unref(paginationRef)!
    const enablePagination = isObject(_pagination)
    const queryParams = {
      ...params,
    }
    if (enablePagination) {
      /**
       * !current和pageSize参数可依照具体项目更改参数，但整个项目尽量保持统一
       */
      Object.assign(queryParams, {
        current: _pagination.current,
        pageSize: _pagination.pageSize,
        ...queryParams,
      })
    }
    loadingRef.value = true
    const data = await props?.dataRequest?.(queryParams).finally(() => {
      loadingRef.value = false
    })
    if (isObject(data)) {
      const { size, total, pages, records } = data
      if (enablePagination && _pagination?.current) {
        /**有分页时，删除当前页最后一条数据时，自动向前一页查询 */
        if (records?.length === 0 && total > 0 && pages > 1) {
          _pagination.current--
          return reload()
        }
      }
      Object.assign(unref(paginationRef)!, {
        pageSize: size,
        current: pages,
        total,
      })
    }
    if (isArray(data)) {
      tableData.value = data
    } else {
      tableData.value = []
    }
    return tableData
  }
  /**
   * @description: 刷新表格
   * @param {boolean} resetPageIndex 是否跳转到第一页
   * @return {*} 表格数据
   * @author: yanjikun
   */
  const reload = async (resetPageIndex: boolean = false): Promise<Ref<any[]>> => {
    const pagination = unref(paginationRef)
    if (Object.is(resetPageIndex, true) && isObject(pagination)) {
      pagination.current = 1
    }
    return await fetchData()
  }
  const handleTableChange: OnChangeCallbackParams = (...rest) => {
    const [pagination] = rest
    if (Object.keys(pagination).length) {
      Object.assign(unref(paginationRef)!, pagination)
    }
    fetchData()
    emit('change', rest)
  }
  /**
   * @description: 获取表格列key
   * @param {TableColumn} column
   * @return {*}
   * @author: yanjikun
   */
  const getColumnKey = (column: TableColumn) => {
    return column?.key || column?.dataIndex
  }
  return {
    setProps,
    getComponent,
    queryTable,
    fetchData,
    reload,
    handleTableChange,
    getColumnKey,
  }
}
